import {defineStore} from "pinia";
import {
    bindUserDept,
    changePassword,
    createCode,
    createUserId,
    getInfo, getUserInfoByU,
    login,
    logout,
    publicKey, queryUser, queryUserByDeptId,
    register, setUserApprover, updateUser,
    verifyCode
} from "@/api/user";
import {ILogin, IPassword, IRegister, IUser} from "@/iwb/IUser";
import {updateAvatar} from "@/api/file";
import {DialogUtils} from "@/utils/DialogUtils";
import {RefreshUtils} from "@/utils/RefreshUtils";
import {StorageUtils} from "@/utils/StorageUtils";
import {RsaUtils} from "@/utils/RsaUtils";
import {useEncryptStore} from "@/store/encrypt";
import {SignUtils} from "@/utils/SignUtils";

export const useUserStore = defineStore('userStore', {
    state: () => ({
        token: undefined,
        userInfo: {} as IUser,
        login: {} as ILogin,
        loginname: '',
        publicKey: '',
        uuid: ''
    }),
    persist: {
      enabled: true
    },
    actions: {
        /**
         * 获取唯一ID
         */
        getUUID() {
            if (this.uuid === '') {
                this.uuid = SignUtils.uuid();
            }
            return this.uuid;
        },
        /**
         * 注册账号
         * @param userInfo
         */
        toRegister(userInfo: IRegister) {
            return new Promise((resolve, reject) => {
                const {username, nickname, password, loginphone, sharecode} = userInfo;
                this.storePublicKey().then((publicKey: any) => {
                    RsaUtils.setPublicKey(publicKey);
                    register({
                        username: RsaUtils.RsaEncrypt(username),
                        nickname: RsaUtils.RsaEncrypt(nickname),
                        password: RsaUtils.RsaEncrypt(password),
                        loginphone: RsaUtils.RsaEncrypt(loginphone), sharecode}).then(res => {
                        const {data} = res;
                        resolve(data);
                    }).catch(error=>{
                        reject(error);
                    })
                })
            })
        },
        /**
         * 修改用户密码
         * @param password
         */
        toChangePassword(password: IPassword) {
            return new Promise((resolve, reject) => {
                const {oldPassword, newPassword} = password;
                changePassword({oldPassword, newPassword}).then(res => {
                    const {data}  = res;
                    resolve(data)
                }).catch(error => {
                    reject(error);
                })
            })
        },
        /**
         * 预登录系统，获取RSA公钥，发送AES私钥，加密数据
         */
        preLoginSystem() {
            return new Promise((resolve, reject) => {
                publicKey().then(response => {
                    const { data } = response;
                    //获取到了公钥之后，后续每次请求都携带AES钥给后端
                    resolve(data);
                }).catch(error => {
                    reject(error);
                })
            })
        },
        /**
         * 登录系统
         * @param loginname
         * @param password
         * @param code
         */
        loginSystem(loginname: string, password: string, code: string) {
            return new Promise((resolve, reject) => {
                let uuid = StorageUtils.getStorage0('uuid');
                this.storePublicKey().then((publicKey: any) => {
                    const encryptStore = useEncryptStore();
                    encryptStore.getAesKey().then((resKey: any) => {
                        let key = JSON.stringify(resKey);
                        RsaUtils.setPublicKey(publicKey);
                        //console.log(uuid);
                        login({ loginname: RsaUtils.RsaEncrypt(loginname.trim()), password: RsaUtils.RsaEncrypt(password), code: code, uuid: uuid, key: RsaUtils.RsaEncrypt(key) }).then(response => {
                            const { data } = response;
                            this.login.userId = data.userId;
                            this.login.nickname = data.nickname;
                            this.login.username = data.username;
                            this.login.loginphone = data.loginphone;
                            this.login.email = data.email;
                            this.loginname = loginname; ///记录账户的登录名
                            // 由于使用了store持久化工具，所以只要登录，就主动将用户信息设置为空
                            this.token = data.token;
                            resolve(this.login);
                        }).catch(error => {
                            reject(error)
                        })
                    }).catch(error => {
                        reject(error);
                    })
                })
            })
        },
        resetToken() {
            const that = this;
            return new Promise(resolve => {
                that.token = undefined;
                that.userInfo = {} as IUser;
                that.login = {} as ILogin;
                resolve('ok')
            })
        },
        storePublicKey() {
            const loading = RefreshUtils.refreshLoading('加载公钥中');
            return new Promise((resolve, reject) => {
                publicKey().then((res: any) => {
                    const { data } = res;
                    //console.warn(res);
                    if (data.encodedInternal) {
                        this.publicKey = '-----BEGIN PUBLIC KEY-----' + data.encodedInternal + '-----END PUBLIC KEY-----';
                        resolve(this.publicKey);
                        loading.close();
                    } else {
                        reject(res.message);
                        loading.close();
                    }
                }).catch(error => {
                    loading.close();
                    reject(error);
                })
            })
        },
        getPublicKey() {
            return this.publicKey;
        },
        abortLogoutSystem() {
            const loading = RefreshUtils.refreshLoading('退出系统中');
            this.userInfo = {} as IUser;
            this.login = {} as ILogin;
            this.token = undefined;
            loading.close();
        },
        logoutSystem() {
            const loading = RefreshUtils.refreshLoading('退出系统中');
            return new Promise((resolve, reject) => {
                logout().then(() => {
                    // 由于使用了store持久化工具，所以只要登录，就主动将用户信息设置为空
                    this.userInfo = {} as IUser;
                    this.login = {} as ILogin;
                    this.token = undefined;
                    loading.close();
                    resolve('');
                }).catch(error => {
                    loading.close();
                    reject(error);
                })
            })
        },
        toUpdateAvatar(avatarInfo: any) {
            const {formData, userInfo} = avatarInfo;
            return new Promise((resolve, reject) => {
                updateAvatar(formData).then(response => {
                    const { data } = response;
                    StorageUtils.updateLoginRecord(data.path_url);
                    userInfo.avatarUrl = data.path_url;
                    this.userInfo = userInfo;
                    resolve(userInfo);
                }).catch(error => {
                    reject(error);
                })
            })
        },
        /**
         * 通过手机号获取邀请码
         * @param mobilePhone
         */
        toCreateCode(mobilePhone: string) {
            return new Promise((resolve, reject) => {
                createCode(mobilePhone).then(res => {
                    const { data } = res;
                    resolve(data);
                }).catch(error => {
                    reject(error);
                })
            })
        },
        /**
         * 批量生成用户ID
         * @param beginId
         * @param endId
         */
        toCreateUserId(beginId: number, endId: number) {
            return new Promise((resolve, reject) => {
                createUserId(beginId, endId).then(res => {
                    resolve(res);
                }).catch(error => {
                    reject(error);
                })
            })
        },
        getUserInfo() {
            return new Promise((resolve, reject) => {
                console.log(this.login);
                const loading = RefreshUtils.refreshLoading('努力加载用户数据中');
                getInfo(this.login.userId).then((res: any) => {
                    const { data } = res;
                    if (!data && res.code != 204) {
                        reject('令牌认证失败，请重新登录！')
                    }
                    if(!data) {
                        loading.close();
                        resolve(false);
                    } else {
                        this.userInfo = data || {};
                        console.log(data);
                        StorageUtils.updateLoginRecord(this.userInfo.avatarUrl);
                        loading.close();
                        resolve(true);
                    }
                }).catch((error) => {
                    console.error(error);
                    loading.close();
                    //数据加载发生异常，提示用户是否重新加载
                    DialogUtils.showMessageBox('提示', '数据加载异常，是否重新尝试？', {
                        confirmButtonText: '重新加载',
                        cancelButtonText: '退出登录',
                        type: 'warning'
                    }).then(() => {
                        location.reload();
                        this.getUserInfo();
                    }).catch(() => {
                        reject(false);
                        this.abortLogoutSystem();
                    });
                })
            })
        },
        /**
         * 获取登录验证码
         */
        newVerifyCode() {
            return new Promise((resolve, reject) => {
                verifyCode().then(res => {
                    StorageUtils.addStorage('uuid', res.data.uuid);
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            });
        },
        /**
         * 绑定部门信息
         * @param data
         */
        bindUserDept(data: IUser) {
            return new Promise(((resolve, reject) => {
                bindUserDept(data).then(res => {
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            }))
        },
        /**
         * 获取当前部门下用户信息
         * @param pageIndex
         * @param pageSize
         * @param deptId
         */
        queryUserByDeptId(pageIndex: number, pageSize: number, deptId: number) {
            return new Promise(((resolve, reject) => {
                queryUserByDeptId(pageIndex, pageSize, deptId).then(res => {
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            }))
        },
        /**
         * 设置用户是否是审批人
         * @param userId
         * @param enable
         */
        setUserApprover(userId: Array<number>, enable: boolean) {
            return new Promise(((resolve, reject) => {
                setUserApprover({userId, enable}).then(res => {
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            }))
        },
        /**
         * 分页查询人员信息
         * @param pageIndex
         * @param pageSize
         */
        queryUser(pageIndex: number, pageSize: number) {
            return new Promise(((resolve, reject) => {
                queryUser(pageIndex, pageSize).then(res => {
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            }))
        },
        /**
         * 更新用户信息
         * @param user
         */
        updateUser(user: IUser) {
            return new Promise(((resolve, reject) => {
                updateUser(user).then(res => {
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            }))
        },
        /**
         * 查询用户
         * @param user
         * @param isOr
         */
        getUserInfoByU(user: IUser, isOr: boolean) {
            return new Promise(((resolve, reject) => {
                getUserInfoByU(user, isOr).then(res => {
                    resolve(res);
                }).catch(error=>{
                    reject(error);
                })
            }))
        }
    }
})
